
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.Net.Sockets;
using System.Xml.Serialization;
using System.IO;

namespace Tanks
{
    public enum Direction
    {
        Up, Right, Down, Left
    }

    public enum BonusType//бонусы, время от времени появляющиеся на карте
    {
        Rate = 0, Speed_bullet = 1, Speed_tank = 2, Immortality = 3, Invisibility = 4
        ///Rate - скорострельность
        ///Speed_bullet - скорость полета пуль
        ///Speed_tank - скорость движения танка
        ///Immortality - бессмертие
        ///Invisibility - невидимость
    }

    public partial class MainPage : UserControl
    {
        Direction direction = Direction.Up;//направление движения танка
        Tank tank; //Управляемый нами танк
        bool allow_create_new = false; //флаг на то, находимся ли мы в режиме редактора карты
        Point p1, p2;
        Map map = new Map();
        Wall movable = null;//необходима для редактора карт
        Point start_moving;//необходима для редактора карт
        DateTime dt_prev = DateTime.Now;///для анализа скорострельности
        ///используется в обработчике события KeyPressDown (при анализе нажатия Shift)

        DispatcherTimer change_tank_timer;//таймер проверяет изменения танков 
        DispatcherTimer change_bullet_timer;//таймер проверяет изменения пуль 
        //DispatcherTimer change_map_timer;//таймер проверяет изменения самой карты
        DispatcherTimer bonus_timer;

        PacketTank new_tank_packet = null;//таймер будет проверять этот пакет на наналичие новых танков на карте
        PacketTank changed_tank_packet = null;//таймер будет проверять этот пакет на изменение состояний танков
        PacketBullet new_bullet_packet = null;//таймер будет проверять этот пакет на появление новой пули

        PacketMap[] new_map_packet = null,current_map_packet;

        private Socket socket;

        bool connected = false;//переменная сообщает нам, подключены ли мы к серверу

        public MainPage()
        {
            InitializeComponent();
            ((App)Application.Current).Main_canvas = root_canvas;
            ((App)Application.Current).map = map;
            ((App)Application.Current).Stat = Stat_list;
            ((App)Application.Current).MP = this;
            ((App)Application.Current).Frags_list = frags_list;
            change_tank_timer = new DispatcherTimer();
            change_tank_timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
            change_tank_timer.Tick += new EventHandler(change_tank);

            change_bullet_timer = new DispatcherTimer();
            change_bullet_timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
            change_bullet_timer.Tick += new EventHandler(change_bullet);

            bonus_timer = new DispatcherTimer();
            Random r = new Random();
            bonus_timer.Interval = new TimeSpan(0, 0, 0, r.Next(10, 20));
            bonus_timer.Tick += new EventHandler(bonus_handler);
            bonus_timer.Start();

            //this.KeyDown += new KeyEventHandler(path1_KeyDown);
        }

        void bonus_handler(object sender, EventArgs e)//обработчик таймера, отвечающего за появление бонусов на экране
        {
            Random r = new Random();
            if (((App)Application.Current).bonus != null)
                ((App)Application.Current).Main_canvas.Children.Remove(((App)Application.Current).bonus.Rect);
            switch (r.Next(4))
            {
                case 0:
                    {
                        ((App)Application.Current).bonus = new Bonus(BonusType.Rate, new Point(350, 250));
                        break;
                    }
                case 1:
                    {
                        ((App)Application.Current).bonus = new Bonus(BonusType.Speed_bullet, new Point(350, 250));
                        break;
                    }
                case 2:
                    {
                        ((App)Application.Current).bonus = new Bonus(BonusType.Speed_tank, new Point(350, 250));
                        break;
                    }
                case 3:
                    {
                        ((App)Application.Current).bonus = new Bonus(BonusType.Invisibility, new Point(350, 250));
                        break;
                    }
            }
            bonus_timer.Interval = new TimeSpan(0, 0, 0, r.Next(10, 20));
        }

        void change_tank(object sender, EventArgs e)//обработчик таймера, отвечающего за изменения состояний вражеских танков
        {
            if (new_tank_packet != null)
            {
                Tank new_tank = new Tank(new_tank_packet.Team, new_tank_packet.Pos, new_tank_packet.Dir, new_tank_packet.Id);
                ((App)Application.Current).Tanks.Add(new_tank);
                new_tank.Name = new_tank_packet.Name;
                new_tank.Frags = new_tank_packet.Frags;
                new_tank_packet = null;
                send_tank_info();
            }
            if (changed_tank_packet != null)
            {
                Tank ch_t = return_tank_from_list(changed_tank_packet.Id);
                ch_t.Position = changed_tank_packet.Pos;
                ch_t.Course = changed_tank_packet.Dir;
                if (changed_tank_packet.Speed_Bullet == 15)
                    ch_t.apply_speed_bullet_bonus();
                if (changed_tank_packet.Invisibility == 0)
                    ch_t.make_enemy_invisible();
                ch_t.draw(true, true, true, true);
                changed_tank_packet = null;
            }
        }

        void change_bullet(object sender, EventArgs e)//обработчик таймера, отвечающего за появление вражеских пуль
        {
            if (new_bullet_packet != null)
            {
                Tank tt = return_tank_from_list(new_bullet_packet.Id_tank);
                Bullet bull = new Bullet(tt, false);
                new_bullet_packet = null;
            }
        }

        void add_to_map_list(PacketMap []pac)
        {
            Dispatcher.BeginInvoke(
           delegate()
           {
               maps_list.Items.Clear();
               string s;
               foreach (PacketMap pm in pac)
               {
                   ListBoxItem it = new ListBoxItem();
                   it.Content = pm.Name;
                   maps_list.Items.Add(it);
               }
           });
        }


        private void path1_KeyDown(object sender, KeyEventArgs e)//обработчик нажатия клавиш
        {
            if (e.Key == Key.Up)
            {
                if (direction == Direction.Up)
                    tank.move_up();
                else
                    tank.rotate_up();
                direction = Direction.Up;
                if (connected)
                    send_tank_info();
            }

            if (e.Key == Key.Left)
            {
                if (direction == Direction.Left)
                    tank.move_left();
                else
                    tank.rotate_left();
                direction = Direction.Left;
                if (connected)
                    send_tank_info();
            }
            if (e.Key == Key.Right)
            {
                if (direction == Direction.Right)
                    tank.move_right();
                else
                    tank.rotate_right();
                direction = Direction.Right;
                if (connected)
                    send_tank_info();
            }

            if (e.Key == Key.Down)
            {
                if (direction == Direction.Down)
                    tank.move_down();
                else
                    tank.rotate_down();
                direction = Direction.Down;
                if (connected)
                    send_tank_info();
            }
            if (e.Key == Key.Shift || e.Key == Key.Ctrl)
            {
                DateTime temp = DateTime.Now;
                if ((temp - dt_prev).TotalMilliseconds > tank.Rate)
                {
                    Bullet bull = new Bullet(tank, true);
                    dt_prev = temp;
                }

            }

        }


        private void checkBox_map_editor_Checked(object sender, RoutedEventArgs e)
        {
            allow_create_new = true;
        }

        private void root_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point temp = e.GetPosition(root_canvas);
            if (checkBox_map_editor.IsChecked == true )
            {
                foreach (Wall w in map.List_of_walls)
                {
                    if (temp.X > w.Left_up.X && temp.X < w.Right_down.X && temp.Y > w.Left_up.Y && temp.Y < w.Right_down.Y)//если мы находимся над стенкой
                    {
                        movable = w;
                        Cursor = Cursors.Hand;
                        start_moving = e.GetPosition(movable.Rect);
                        return;
                    }
                }
                movable = null;
                p1 = e.GetPosition(root_canvas);
                allow_create_new = true;
            }
        }

        private void root_canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (allow_create_new == true)
            {
                p2 = e.GetPosition(root_canvas);
                if (p2.X < p1.X || p2.Y < p1.Y)
                    return;
                allow_create_new = false;
                Wall w = new Wall(p1, p2);
                allow_create_new = false;
                map.List_of_walls.Add(w);
            }
            if (movable != null)
            {
                Cursor = Cursors.Arrow;
                movable = null;
            }
        }

        private void root_canvas_MouseMove(object sender, MouseEventArgs e)//обработчик перемещения стенок
        {
            if (movable != null)
            {
                Point now_root = e.GetPosition(root_canvas);
                //если мы залезли на другую стенку
                foreach (Wall w in ((App)Application.Current).map.List_of_walls)
                {
                    if (w == movable)
                        continue;
                    //вбок перемещаем
                    if (now_root.X - start_moving.X > w.Left_up.X && now_root.X - start_moving.X < w.Right_down.X && now_root.Y - start_moving.Y + movable.Height > w.Left_up.Y && now_root.Y - start_moving.Y < w.Right_down.Y)
                    {
                        return;
                    }
                    //вниз/вверх перемещаем
                    if (now_root.Y - start_moving.Y + movable.Height > w.Left_up.Y && now_root.Y - start_moving.Y < w.Right_down.Y && now_root.X - start_moving.X + movable.Width > w.Left_up.X && now_root.X - start_moving.X < w.Right_down.X)
                    {
                        return;
                    }
                }

                //если мы вышли за пределы холста
                if (now_root.X - start_moving.X < 0 || now_root.Y - start_moving.Y < 0 || now_root.X - start_moving.X > 746 - movable.Width || now_root.Y - start_moving.Y > 596 - movable.Height)
                {
                    if (now_root.X - start_moving.X < 0)
                        movable.Left_up = new Point(0, movable.Left_up.Y);
                    if (now_root.Y - start_moving.Y < 0)
                        movable.Left_up = new Point(movable.Left_up.X, 0);
                    if (now_root.X - start_moving.X > 746 - movable.Width)
                        movable.Left_up = new Point(746 - movable.Width, movable.Left_up.Y);
                    if (now_root.Y - start_moving.Y > 596 - movable.Height)
                        movable.Left_up = new Point(movable.Left_up.X, 596 - movable.Height);
                    return;
                }
                else
                {
                    Point pt = new Point();
                    pt.X = now_root.X - start_moving.X;
                    pt.Y = now_root.Y - start_moving.Y;
                    movable.Left_up = pt;
                }

            }
        }

        private void checkBox_map_editor_Checked_1(object sender, RoutedEventArgs e)//показываем кнопки добавления баз
        {
            buttonBase2.Visibility = Visibility.Visible;
            buttonBase1.Visibility = Visibility.Visible;
            //this.KeyDown -= new KeyEventHandler(path1_KeyDown);
        }

        private void checkBox_map_editor_Unchecked(object sender, RoutedEventArgs e)//прячем кнопки добавления баз
        {
            buttonBase2.Visibility = Visibility.Collapsed;
            buttonBase1.Visibility = Visibility.Collapsed;
            //this.KeyDown += new KeyEventHandler(path1_KeyDown);
        }

        private void button2_Click(object sender, RoutedEventArgs e)//добавляет базу на карту
        {
            Wall w;
            if (((Button)sender).Name == "buttonBase1")
            {
                w = new Wall(new Point(0, 0), "red_flag.png");
                buttonBase1.IsEnabled = false;
            }
            else
            {
                w = new Wall(new Point(695, 535), "blue_flag.png");
                buttonBase2.IsEnabled = false;
            }
            map.List_of_walls.Add(w);
            
        }

        private void root_canvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            Point temp = e.GetPosition(root_canvas);
            foreach (Wall w in map.List_of_walls)
            {
                if (temp.X > w.Left_up.X && temp.X < w.Right_down.X && temp.Y > w.Left_up.Y && temp.Y < w.Right_down.Y)//если мы нажали мышкой на стенку
                {
                    double add = 0;
                    if (e.Delta > 0)
                        add = 5;
                    else
                        add = -5;
                    w.Right_down = new Point(w.Right_down.X + add, w.Right_down.Y + add);
                    return;
                }
            }
        }

        private void buttonConnect_Click(object sender, RoutedEventArgs e)
        {
            //если есть открытые сокеты
            try
            {
                if (connected == true)
                    return;
                if ((socket != null) && (socket.Connected))
                    socket.Close();
            }
            catch (Exception err)
            {
                update("ERROR: " + err.Message);
            }

            //идентификация удаленного узла
            try
            {
                DnsEndPoint endPoint = new DnsEndPoint("localhost", 4530);

                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();//дополнительные данные

                args.UserToken = socket;//для передачи соостояния обработчику событий Completed
                args.RemoteEndPoint = endPoint;// идентифик удаленного узла

                //событие завершения асинхронной операции (любой)
                args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);//подписываемся на событие
                socket.ConnectAsync(args);// создаем соединение
                change_tank_timer.Start();
                change_bullet_timer.Start();
            }
            catch (Exception exc)
            {
            }
        }

        private void OnSocketConnectCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (!socket.Connected)
            {
                update("Failed.");
                return;
            }
            update("Connected");
            connected = true;

            byte[] response = new byte[20000];
            //e - объект в котором собраны данные о подключение
            e.SetBuffer(response, 0, response.Length);//задаем буфер данных для приема
            e.Completed -= new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);//убираем старый обработчик т.к. нужно ослеживать уже другое событие
            e.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketReceive);//подписываемся на событие получения данных
            // принятие данных
            socket.ReceiveAsync(e);
            ((App)Application.Current).Socket_app = socket;
            send_count_request();
            send_tank_info();//послать всем клиентским приложениям сообщение о новом подключении
        }

        private void update(string message)
        {
            Dispatcher.BeginInvoke(
            delegate()
            {
                textBlock1.Text = message;
            });
        }

        private void OnSocketReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred == 0)
            {//если ничего не принято
                update("Server disconnected.");
                try
                {
                    socket.Close();
                }
                catch { }
                return;

            }
            try//если пришла инфа про танк
            {
                
                XmlSerializer serializer = new XmlSerializer(typeof(PacketTank));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                PacketTank message = (PacketTank)serializer.Deserialize(ms);
                if (is_tank_already_connected(message.Id) == false)
                {
                    new_tank_packet = message;
                }
                else
                {
                    changed_tank_packet = message;
                }
                //return;
            }
            catch (Exception) { }

            try//если пришла инфа про пулю
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PacketBullet));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                PacketBullet message = (PacketBullet)serializer.Deserialize(ms);
                new_bullet_packet = message;
            }
            catch (Exception) { }

            try//если пришел список карт
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PacketMap[]));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                PacketMap[] messages = (PacketMap[])serializer.Deserialize(ms);
                current_map_packet = messages;
                add_to_map_list(messages);
            }
            catch (Exception err)
            {}

            try//если пришла карта
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PacketMap));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                PacketMap message = (PacketMap)serializer.Deserialize(ms);
                add_to_map(message.wallinfo_array);
                //new_map_packet = message;
            }
            catch (Exception err)
            { }

            try//если пришло число клиентов
            {
                XmlSerializer serializer = new XmlSerializer(typeof(int));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                int message = (int)serializer.Deserialize(ms);
                if (message == 1)
                    main_on();
            }
            catch (Exception err)
            { }

            try//если пришло сообщение о начале игры
            {
                XmlSerializer serializer = new XmlSerializer(typeof(string));
                MemoryStream ms = new MemoryStream(e.Buffer, 0, e.BytesTransferred);
                string message = (string)serializer.Deserialize(ms);
                show_timer_window();
            }
            catch (Exception err)
            { }

            socket.ReceiveAsync(e);
        }

        void show_timer_window()
        {
            Dispatcher.BeginInvoke(
                delegate()
                {
                    TimerWindow tw = new TimerWindow();
                    tw.Closed += new EventHandler(tw_Closed1);
                    tw.Show();
                });
        }

        void tw_Closed1(object sender, EventArgs e)
        {
            this.KeyDown += new KeyEventHandler(path1_KeyDown);
            ((TimerWindow)sender).Closed -= new EventHandler(tw_Closed1);
        }

        void main_on()//разрешает клиенту начать игру и выбрать карту
        {
            Dispatcher.BeginInvoke(
                delegate()
                {
                    buttonStart.IsEnabled = true;
                    maps_list.IsEnabled = true;
                }
            );
        }

        private void send_tank_info()//отсылает инфу о танке
        {
            if ((socket == null) || (socket.Connected == false))
            {
                update("нет соединения");
                return;
            }
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();

            PacketTank p = new PacketTank();
            p.Dir = tank.Course;
            p.Pos = tank.Position;
            p.Id = tank.ID;
            p.Speed_Bullet = tank.Speed_bullet;
            p.Invisibility = tank.Invisibility;
            p.Team = tank.Team;
            p.Name = tank.Name;
            p.Damage = tank.Damage;
            p.Frags = tank.Frags;

            //создаем объект для сериализации 
            XmlSerializer serializer = new XmlSerializer(typeof(PacketTank));
            //подготовка сообщения
            MemoryStream ms = new MemoryStream();

            //сериалиция объекта PaketTank в поток байтов
            serializer.Serialize(ms, p);

            byte[] messageData = ms.ToArray();

            List<ArraySegment<byte>> bufferList = new List<ArraySegment<byte>>();
            bufferList.Add(new ArraySegment<byte>(messageData));
            args.BufferList = bufferList;

            socket.SendAsync(args);
        }

        void send_map_info(string n)//отсылает инфу о карте
        {
            if ((socket == null) || (socket.Connected == false))
            {
                update("нет соединения");
                return;
            }
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();

            PacketMap p = new PacketMap();
            p.wallinfo_array = convert_list_of_walls_to_wallinfo_array();
            p.Name = n;

            //создаем объект для сериализации 
            XmlSerializer serializer = new XmlSerializer(typeof(PacketMap));
            //подготовка сообщения
            MemoryStream ms = new MemoryStream();

            //сериалиция объекта PaketTank в поток байтов
            serializer.Serialize(ms, p);

            byte[] messageData = ms.ToArray();

            List<ArraySegment<byte>> bufferList = new List<ArraySegment<byte>>();
            bufferList.Add(new ArraySegment<byte>(messageData));
            args.BufferList = bufferList;

            socket.SendAsync(args);
        }

        void send_count_request()//запрос на количетсво подключенных клиентов
        {
            if ((socket == null) || (socket.Connected == false))
            {
                update("нет соединения");
                return;
            }
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            XmlSerializer serializer = new XmlSerializer(typeof(int));
            MemoryStream ms = new MemoryStream();
            serializer.Serialize(ms, 1);
            byte[] messageData = ms.ToArray();
            List<ArraySegment<byte>> bufferList = new List<ArraySegment<byte>>();
            bufferList.Add(new ArraySegment<byte>(messageData));
            args.BufferList = bufferList;
            socket.SendAsync(args);
        }

        void send_start_game_info()
        {
            if ((socket == null) || (socket.Connected == false))
            {
                update("нет соединения");
                return;
            }
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            XmlSerializer serializer = new XmlSerializer(typeof(string));
            MemoryStream ms = new MemoryStream();
            serializer.Serialize(ms, "start");
            byte[] messageData = ms.ToArray();
            List<ArraySegment<byte>> bufferList = new List<ArraySegment<byte>>();
            bufferList.Add(new ArraySegment<byte>(messageData));
            args.BufferList = bufferList;
            socket.SendAsync(args);
        }

        bool is_tank_already_connected(int id)//функция определяет, есть ли уже такой танк в списке
        {
            foreach (Tank temp in ((App)Application.Current).Tanks)
            {
                if (temp.ID == id)
                    return true;
            }
            return false;
        }

        bool is_bullet_already_exist(int id)//функция определяет, есть ли уже такая пуля в списке
        {
            foreach (Bullet temp in ((App)Application.Current).Bullets)
            {
                if (temp.Id == id)
                    return true;
            }
            return false;
        }

        Tank return_tank_from_list(int id)//функция возращает конкретный танк из списка танков
        {
            foreach (Tank temp in ((App)Application.Current).Tanks)
            {
                if (temp.ID == id)
                    return temp;
            }
            return null;
        }

        Bullet return_bullet_from_list(int id)//функция возращает конкретная пуля из списка пуль
        {
            foreach (Bullet temp in ((App)Application.Current).Bullets)
            {
                if (temp.Id == id)
                    return temp;
            }
            return null;
        }

        private void MainUSerControl_Loaded(object sender, RoutedEventArgs e)//вывод стартового окошка
        {
            ChildWindow_start cw = new ChildWindow_start();
            cw.Closed += new EventHandler(cw_Closed);
            cw.Show();
        }

        void cw_Closed(object sender, EventArgs e)
        {
            ChildWindow_start cc = (ChildWindow_start)sender;
            if (cc.DialogResult == true)
            {
                if (cc.radioButtonRed.IsChecked == true)
                {
                    direction = Direction.Down;
                    tank = new Tank(Colors.Red, new Point(60, 10), Direction.Down, 0);
                    ((App)Application.Current).Tanks.Add(tank);
                    tank.Name = cc.textBox1.Text;
                }
                if (cc.radioButtonBlue.IsChecked == true)
                {
                    direction = Direction.Up;
                    tank = new Tank(Colors.Blue, new Point(600, 540), Direction.Up, 0);
                    ((App)Application.Current).Tanks.Add(tank);
                    tank.Name = cc.textBox1.Text;
                }
            }
        }

        void add_to_map(WallInfo[] array)//перегоняет массив стенок в корневой спикок стен
        {
            
            
            Dispatcher.BeginInvoke(
            delegate()
            {
                foreach (Wall wl in map.List_of_walls)
                    root_canvas.Children.Remove(wl.Rect);

                map.List_of_walls.Clear();
                Wall w;
                foreach (WallInfo wi in array)
                {
                    if (wi.background == "bricks_small.jpg")
                        w = new Wall(wi.left_up, wi.right_down);
                    else
                        w = new Wall(wi.left_up, wi.background);
                    map.List_of_walls.Add(w);
                }
            });
        }
        void add_to_map_this_thread(WallInfo[] array)//перегоняет массив стенок в корневой спикок стен
        {
                foreach (Wall wl in map.List_of_walls)
                    root_canvas.Children.Remove(wl.Rect);

                map.List_of_walls.Clear();
                Wall w;
                foreach (WallInfo wi in array)
                {
                    if (wi.background == "bricks_small.jpg")
                        w = new Wall(wi.left_up, wi.right_down);
                    else
                        w = new Wall(wi.left_up, wi.background);
                    map.List_of_walls.Add(w);
                }
        }

        WallInfo[] convert_list_of_walls_to_wallinfo_array()
        {
            WallInfo[] wi = new WallInfo[map.List_of_walls.Count];
            int i = 0;
            foreach (Wall w in map.List_of_walls)
            {
                wi[i].left_up = w.Left_up;
                wi[i].right_down = w.Right_down;
                wi[i++].background = w.background;
            }
            return wi;
        }


        public void begin_new_game(Color c)//начинает новую игру
        {
            GameOverWindow g = new GameOverWindow(c);
            g.Closed += new EventHandler(g_Closed);
            change_tank_timer.Stop();
            g.Show();
        }


        void g_Closed(object sender, EventArgs e)
        {
            if (((GameOverWindow)sender).DialogResult == true)
            {
                ((App)Application.Current).Main_canvas.Children.Clear();
                ((App)Application.Current).Tanks.Clear();
                ((App)Application.Current).map.List_of_walls.Clear();
                buttonBase1.IsEnabled = false;
                buttonBase2.IsEnabled = false;

                string nm = tank.Name;
                int fr = tank.Frags;
                if (tank.Team == Colors.Red)
                {
                    direction = Direction.Down;
                    tank = new Tank(Colors.Red, new Point(60, 10), Direction.Down, 0);
                    ((App)Application.Current).Tanks.Add(tank);
                    tank.Name = nm;
                    tank.Frags = fr;
                }
                else
                {
                    direction = Direction.Up;
                    tank = new Tank(Colors.Blue, new Point(650, 535), Direction.Up, 0);
                    ((App)Application.Current).Tanks.Add(tank);
                    tank.Name = nm;
                    tank.Frags = fr;
                }
                this.KeyDown -= new KeyEventHandler(path1_KeyDown);
                send_tank_info();
                change_tank_timer.Start();
            }
        }

        private void buttonSave_Click(object sender, RoutedEventArgs e)//отправка карты на сервер
        {
            MapWindow mw = new MapWindow();
            mw.Closed += new EventHandler(mw_Closed);
            mw.Show();
        }

        void mw_Closed(object sender, EventArgs e)
        {
            MapWindow m = (MapWindow)sender;
            if (m.DialogResult == true)
                send_map_info(m.textBox1.Text);
            m.Closed -= new EventHandler(mw_Closed);
        }

        private void buttonLoad_Click(object sender, RoutedEventArgs e)//чтение списка карт с сервера
        {
            if ((socket == null) || (socket.Connected == false))
            {
                update("нет соединения");
                return;
            }
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            XmlSerializer serializer = new XmlSerializer(typeof(bool));
            MemoryStream ms = new MemoryStream();
            serializer.Serialize(ms, true);
            byte[] messageData = ms.ToArray();
            List<ArraySegment<byte>> bufferList = new List<ArraySegment<byte>>();
            bufferList.Add(new ArraySegment<byte>(messageData));
            args.BufferList = bufferList;
            socket.SendAsync(args);
        }


        private void maps_list_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox l = (ListBox)sender;
            try
            {
                add_to_map_this_thread(current_map_packet[l.SelectedIndex].wallinfo_array);
                map.Name = current_map_packet[l.SelectedIndex].Name;
                send_map_info(map.Name);
            }
            catch (Exception ex)
            { }
        }

        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            TimerWindow tw = new TimerWindow();
            tw.Closed += new EventHandler(tw_Closed);
            send_start_game_info();
            tw.Show();
        }

        void tw_Closed(object sender, EventArgs e)
        {
            this.KeyDown += new KeyEventHandler(path1_KeyDown);
            ((TimerWindow)sender).Closed -= new EventHandler(tw_Closed);
        }

    }
}

